<?php

namespace teach\controllers;

use teach\components\WeChat;
use teach\service\Calculation;
use teach\service\Notify;
use teach\service\SendWechatMessage;
use teach\service\StarModel;
use teach\service\StarModelAssemble;
use teach\service\UnWelfare;
use teach\util\helper\ResponseHelper;
use Yii;
use yii\filters\VerbFilter;
use yii\web\Controller;

class NotifyController extends Controller
{
    public $enableCsrfValidation = false;

    public function behaviors()
    {
        return [
            'verbs' => [
                'class' => VerbFilter::class,
                'actions' => [
                    '*' => ['get', 'post', 'put', 'delete', 'head', 'options'],
                ],
            ],
        ];
    }

    /**
     * 接收微信回调
     */
    public function actionDirect()
    {
        //接收参数
        $xml = file_get_contents('php://input', 'r');
//        file_put_contents('./log.txt',$xml,FILE_APPEND);
        //将服务器返回的XML数据转化为数组
        //禁用外部xml
        libxml_disable_entity_loader(true);
        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);


        //查找回调 表中是否已经入库
        $notify = new Notify();
        $param = "out_trade_no = '{$data['out_trade_no']}' ";
        $count = $notify->payCount($param);

        //返回数据告诉微信已经接收到数据
        if ($count >= 1) {
            $str = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            return $this->asJson($str);
        }

        //接收到数据并显示支付成功
        if ($data['result_code'] == "SUCCESS") {
            //将订单表改为已经收款
            $parameter = " status = 1 ";
            $parameters = " out_trade_no = '{$data['out_trade_no']}' ";
            $notify->orderPay($parameter, $parameters);


            //放入数组中
            $map['out_trade_no'] = $data['out_trade_no'];          // 订单单号
            $map['openid'] = $data['sub_openid'];                  // 付款人openID
            $map['total_fee'] = ($data['total_fee'] / 100);            // 付款金额 单位分
            $map['transaction_id'] = $data['transaction_id'];  // 微信支付流水号
            $map['status'] = 1;
            $map['create_time'] = time();
            $res = $notify->payInsert($map);

            //查找订单号 如果recharge !=0 则从客户中减去
            $order = $notify->getOrder($map['out_trade_no']);
            if ($order['recharge'] != 0) {
                $notify->subRecharge($order['uid'], $order['recharge']);
            }

            if ($res) {
                //给商家跟用户发送消息
                $this->Send($data['out_trade_no']);
                $str = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            } else {
                $str = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
            }
        } else {
            $str = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
        }

        return $this->asJson($str);
    }

    /**
     * 给商家用户发送小程序消息
     * @param $out_trade_no
     */
    private function Send($out_trade_no)
    {
        $notify = new Notify();
        $where = " out_trade_no = '{$out_trade_no}' ";
        $order = $notify->orderOne($where);
        //$redis = Yii::$app->redis;
        $SendWeChatMessage = new SendWechatMessage();
        $WeChat = new WeChat();
        //发给下单用户
        //小程序模板消息
//        while (true) {
//            $formid = $redis->rpop("formid_{$order['openid']}");
//            $status = $WeChat->sendMsg($SendWeChatMessage->buy($order['openid'], $formid, $out_trade_no, $order['total_fee'], $order['name'], $order['phone'], $order['address']));
//            if ($status['errcode'] == 0 || $formid == false) {
//                break;
//            }
//        }
        //小程序订阅消息
        $WeChat->send($SendWeChatMessage->buys($order["openid"], $order["out_trade_no"], $order["total_fee"], $order["name"], $order["phone"], $order["address"]));

        //查找商家
        $andWhere = " id = {$order['mid']} ";
        $store = $notify->userOne($andWhere);
        //小程序模板消息
//        while (true) {
//            $formid_store = $redis->rpop("formid_{$store['openid']}");
//            $status_store = $WeChat->sendMsg($SendWeChatMessage->wasBuy($store['openid'], $formid_store, $order['total_fee'], $order['name'], $order['phone'], $order['address']));
//            if ($status_store['errcode'] == 0 || $formid_store == false) {
//                break;
//            }
//        }
        //小程序订阅消息
        $WeChat->send($SendWeChatMessage->buys($store["openid"], $order["out_trade_no"], $order["total_fee"], $order["name"], $order["phone"], $order["address"]));

        //查找商家规则
        $filterWhere = " mid = {$order['mid']} ";
        $rule = $notify->ruleOne($filterWhere);

        //如果rule不存在给开发者发送消息
        if (!$rule) {
            while (true) {
                $openid_developer = "oLAZ75aa9tYmJB3mIaLzMfOBcAkA";
                $des = "商家:{$order['mid']}缺少对应的分佣规则,及时补充";
                $project_name = "用户购买中的微信回调";
                $tip = "在mall_distribute 中添加";
                $address = "teach/notify/actionDirect" . json_encode($rule);

                $formid_developer = $redis->rpop("formid_{$openid_developer}");
                $status_developer = $WeChat->sendMsg($SendWeChatMessage->developer($openid_developer, $formid_developer, $des, $project_name, $tip, $address));
                if ($status_developer['errcode'] == 0 || $status_developer == false) {
                    break;
                }
            }
        }

        //查找购买用户的上级跟上上级,判断商家用的是哪种规则,然后根据规则计算积分,然后入库为未结算积分
        if ($rule['state'] == 1) {
            //6折模式
            $UnWelfare = new UnWelfare();
            $UnWelfare->payAll($order['id'], $order['mid'], $order['uid']);
        }

        if ($rule['state'] == 2) {
            //根据商家自己设置的规则发送佣金
            $StarModel = new StarModel();
            $StarModel->payAll($order['id'], $order['mid'], $order['uid']);
        }
    }

    /**
     * 接收用户充值的微信回调
     */
    public function actionRecharge()
    {
        //接收参数
        $xml = file_get_contents('php://input', 'r');
//        file_put_contents('./log.txt',$xml,FILE_APPEND);
        //将服务器返回的XML数据转化为数组
        //禁用外部xml
        libxml_disable_entity_loader(true);
        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);


        //查找回调 表中是否已经入库
        $notify = new Notify();
        $param = "out_trade_no = '{$data['out_trade_no']}' ";
        $count = $notify->rechargeCount($param);

        //返回数据告诉微信已经接收到数据
        if ($count >= 1) {
            $str = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            return $this->asJson($str);
        }

        //接收到数据并显示支付成功
        if ($data['result_code'] == "SUCCESS") {
            //将订单表改为已经收款
            $parameter = " status = 1 ";
            $parameters = " out_trade_no = '{$data['out_trade_no']}' ";
            $notify->rechargePay($parameter, $parameters);


            //放入数组中
            $map['out_trade_no'] = $data['out_trade_no'];          // 订单单号
            $map['openid'] = $data['sub_openid'];                  // 付款人openID
            $map['total_fee'] = ($data['total_fee'] / 100);            // 付款金额 单位分
            $map['transaction_id'] = $data['transaction_id'];  // 微信支付流水号
            $map['status'] = 1;
            $map['create_time'] = time();
            $res = $notify->rechargeInsert($map);

            // 给用户加入等额的充值金额
            $notify->userRecharge($map['openid'], $map['total_fee']);


            if ($res) {
                //给商家跟用户发送消息
                $this->rechargeSend($map['openid'], $map['total_fee']);
                $str = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            } else {
                $str = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
            }
        } else {
            $str = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
        }

        return $this->asJson($str);
    }

    /**
     * 接收代理商充值的微信回调
     */
    public function actionRecharges()
    {
        //接收参数
        $xml = file_get_contents('php://input', 'r');
//        file_put_contents('./log.txt',$xml,FILE_APPEND);
        //将服务器返回的XML数据转化为数组
        //禁用外部xml
        libxml_disable_entity_loader(true);
        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);


        //查找回调 表中是否已经入库
        $notify = new Notify();
        $param = "out_trade_no = '{$data['out_trade_no']}' ";
        $count = $notify->rechargeCount($param);

        //返回数据告诉微信已经接收到数据
        if ($count >= 1) {
            $str = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            return $this->asJson($str);
        }

        //接收到数据并显示支付成功
        if ($data['result_code'] == "SUCCESS") {
            //将订单表改为已经收款
            $parameter = " status = 1 ";
            $parameters = " out_trade_no = '{$data['out_trade_no']}' ";
            $notify->rechargePay($parameter, $parameters);


            //放入数组中
            $map['out_trade_no'] = $data['out_trade_no'];          // 订单单号
            $map['openid'] = $data['openid'];                  // 付款人openID
            $map['total_fee'] = ($data['total_fee'] / 100);            // 付款金额 单位分
            $map['transaction_id'] = $data['transaction_id'];  // 微信支付流水号
            $map['status'] = 1;
            $map['create_time'] = time();

            //手续费
            if ($map['total_fee'] > 0.7) {
                $map['rate'] = number_format($map['total_fee'] * 6 / 1000, 2);
                $map['total_fee'] = number_format($map['total_fee'] - $map['rate'], 2);
            }

            $res = $notify->rechargeInsert($map);

            // 给用户加入等额的充值金额
            $notify->userRecharge($map['openid'], $map['total_fee']);


            if ($res) {
                //给商家跟用户发送消息
                $this->rechargeSend($map['openid'], $map['total_fee']);
                $str = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            } else {
                $str = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
            }
        } else {
            $str = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
        }

        return $this->asJson($str);
    }

    /**
     *发送模板消息告诉用户已经充值了请查看支票
     * @param $openid
     * @param $score
     */
    private function rechargeSend($openid, $score)
    {
        $SendWeChatMessage = new SendWechatMessage();
        $redis = Yii::$app->redis;
        $WeChat = new WeChat();
        $reason = "积分充值成功";
        $tip = "请注意核对查收";
        //发给下单用户
        while (true) {
            $formid = $redis->rpop("formid_{$openid}");
            $status = $WeChat->sendMsg($SendWeChatMessage->payGoods($openid, $formid, $score, $reason, $tip));
            if ($status['errcode'] == 0 || $formid == false) {
                break;
            }
        }
    }

    /**
     * 将未处理的支付订单 用模式1生成到记录表里
     */
    public function actionStateOneBillRecord()
    {
        $request = Yii::$app->request;
        $oid = $request->post('oid');
        $mid = $request->post('mid');
        $uid = $request->post('uid');

        $msg = '';
        $flag = false;
        if (!$oid) {
            $msg = 'oid 不能为空';
        } elseif (!$mid) {
            $msg = 'mid 不能为空';
        } elseif (!$uid) {
            $msg = 'uid 不能为空';
        } else {
            $flag = true;
        }

        if (!$flag) {
            $jsonData = ResponseHelper::buildJsonData(400, $msg);
        } else {
            $UnWelfare = new UnWelfare();
            $UnWelfare->payAll($oid, $mid, $uid);
            $jsonData = ResponseHelper::buildJsonData(200, '成功');
        }
        return $this->asJson($jsonData);


    }

    /**
     * 将未处理的支付订单 用模式2生成到记录表里
     */
    public function actionStateTwoBillScore()
    {
        $request = Yii::$app->request;
        $oid = $request->post('oid');
        $mid = $request->post('mid');
        $uid = $request->post('uid');
        $msg = '';
        $flag = false;
        if (!$oid) {
            $msg = 'oid 不能为空';
        } elseif (!$mid) {
            $msg = 'mid 不能为空';
        } elseif (!$uid) {
            $msg = 'uid 不能为空';
        } else {
            $flag = true;
        }

        if (!$flag) {
            $jsonData = ResponseHelper::buildJsonData(400, $msg);
        } else {
            $StarModel = new StarModel();
            $StarModel->payAll($oid, $mid, $uid);
            $jsonData = ResponseHelper::buildJsonData(200, '成功');
        }
        return $this->asJson($jsonData);
    }

    /**
     * 对记录表完成结算并入账
     * @return \yii\web\Response
     */
    public function actionBillFinish()
    {
        $request = Yii::$app->request;
        $oid = $request->post('oid');
        $uid = $request->post('uid');
        $mid = $request->post('mid');
        $out_trade_no = $request->post('out_trade_no');

        $msg = '';
        $flag = false;
        if (!$oid) {
            $msg = 'oid 不能为空';
        } elseif (!$mid) {
            $msg = 'mid 不能为空';
        } elseif (!$uid) {
            $msg = 'uid 不能为空';
        } elseif (!$out_trade_no) {
            $msg = 'out_trade_no 不能为空';
        } else {
            $flag = true;
        }

        if (!$flag) {
            $jsonData = ResponseHelper::buildJsonData(400, $msg);
        } else {
            $calculation = new Calculation();
            $calculation->add($oid, $uid, $mid, $out_trade_no);
            $jsonData = ResponseHelper::buildJsonData(200, '成功');
        }
        return $this->asJson($jsonData);
    }

    public function actionAssemble()
    {
        //接收参数
        $xml = file_get_contents('php://input', 'r');
//        file_put_contents('./log.txt', $xml, FILE_APPEND);
        //禁用外部xml
        libxml_disable_entity_loader(true);
        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);

        //查找回调 表中是否已经入库
        $notify = new Notify();
        $where = "out_trade_no = '{$data['out_trade_no']}'";
        $count = $notify->payAssembleCount($where);

        if ($count >= 1) {
            $str = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            return $this->asJson($str);
        }

        //接收到数据并显示支付成功
        if ($data['result_code'] == "SUCCESS") {
            //将订单表改为已经收款
            $andWhere = " status = 1 ";
            $filter = " out_trade_no = '{$data['out_trade_no']}'";
            $notify->orderAssemblePay($andWhere, $filter);


            //放入数组中
            $map['out_trade_no'] = $data['out_trade_no'];          // 订单单号
            $map['openid'] = $data['sub_openid'];                  // 付款人openID
            $map['total_fee'] = ($data['total_fee'] / 100);            // 付款金额 单位分
            $map['transaction_id'] = $data['transaction_id'];  // 微信支付流水号
            $map['status'] = 1;
            $map['create_time'] = time();

            //可能有用字段
            $map['appid'] = $data['appid'];
            $map['mch_id'] = $data['mch_id'];
            $map['sub_appid'] = $data['sub_appid'];
            $map['sub_mch_id'] = $data['sub_mch_id'];
            $map['trade_type'] = $data['trade_type'];
            $map['bank_type'] = $data['bank_type'];
            $map['time_end'] = $data['time_end'];

            $res = $notify->payAssembleInsert($map);

            if ($res) {
                //TODO 给商家跟用户发送消息 计算佣金
                $this->sendAssemble($data['out_trade_no']);
                $str = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            } else {
                $str = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
            }

        } else {
            $str = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
        }
        return $this->asJson($str);
    }

    /**
     * @param $out_trade_no
     */
    private function sendAssemble($out_trade_no)
    {
        $notify = new Notify();
        $where = " out_trade_no = '{$out_trade_no}'";
        $assembleOrder = $notify->assembleOrderOne($where);
        //$redis = Yii::$app->redis;
        $SendWeChatMessage = new SendWechatMessage();
        $WeChat = new WeChat();
        //发给下单用户
//        while (true) {
//            $formid = $redis->rpop("formid_{$assembleOrder['openid']}");
//            $status = $WeChat->sendMsg($SendWeChatMessage->buy($assembleOrder['openid'], $formid, $out_trade_no, $assembleOrder['total_fee'], $assembleOrder['name'], $assembleOrder['phone'], $assembleOrder['address']));
//            if ($status['errcode'] == 0 || $formid == false) {
//                break;
//            }
//        }

        //小程序订阅消息
        $WeChat->send($SendWeChatMessage->buys($assembleOrder["openid"], $assembleOrder["out_trade_no"], $assembleOrder["total_fee"], $assembleOrder["name"], $assembleOrder["phone"], $assembleOrder["address"]));


        //查找商家
        $andWhere = " id = {$assembleOrder['mid']} ";
        $store = $notify->userOne($andWhere);
        //小程序模板消息
//        while (true) {
//            $formid_store = $redis->rpop("formid_{$store['openid']}");
//            $status_store = $WeChat->sendMsg($SendWeChatMessage->wasBuy($store['openid'], $formid_store, $assembleOrder['total_fee'], $assembleOrder['name'], $assembleOrder['phone'], $assembleOrder['address']));
//            if ($status_store['errcode'] == 0 || $formid_store == false) {
//                break;
//            }
//        }
        //小程序订阅消息
        $WeChat->send($SendWeChatMessage->buys($store["openid"], $assembleOrder["out_trade_no"], $assembleOrder["total_fee"], $assembleOrder["name"], $assembleOrder["phone"], $assembleOrder["address"]));

        //查找商家规则
        $filterWhere = " mid = {$assembleOrder['mid']} ";
        $rule = $notify->ruleOne($filterWhere);

        //如果rule不存在给开发者发送消息
        if (!$rule) {
//            while (true) {
//                $openid_developer = "oLAZ75aa9tYmJB3mIaLzMfOBcAkA";
//                $des = "商家:{$assembleOrder['mid']}缺少对应的分佣规则,及时补充";
//                $project_name = "用户购买中的微信回调";
//                $tip = "在mall_distribute 中添加";
//                $address = "teach/notify/actionDirect" . json_encode($rule);
//
//                $formid_developer = $redis->rpop("formid_{$openid_developer}");
//                $status_developer = $WeChat->sendMsg($SendWeChatMessage->developer($openid_developer, $formid_developer, $des, $project_name, $tip, $address));
//                if ($status_developer['errcode'] == 0 || $status_developer == false) {
//                    break;
//                }
//            }
        }

        //TODO 查找产品
        $productAssemble = $notify->productAssembleOne($assembleOrder['pid']);
        //查看订单是否有佣金结算规则
        if ($productAssemble && $productAssemble['sub'] == 1) {
            //需要做分佣处理
            //分佣用星级里面的模式进行分
            $StarModelAssemble = new StarModelAssemble();
            $StarModelAssemble->payAll($assembleOrder['id'],$assembleOrder['mid'],$assembleOrder['uid']);

        }
        //直接将支付表改为已经处理

    }
}